package com.liming.user.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.liming.aftersales.client.AfterSalesClient;
import com.liming.auth.client.UserAuthClient;
import com.liming.common.enums.OrderPickupEnum;
import com.liming.common.pojo.dto.order.user.mini.MiniOrderEvaluateDTO;
import com.liming.common.pojo.dto.order.user.mini.MiniOrderQueryPage;
import com.liming.common.pojo.dto.order.user.mini.MiniOrderSelectCouponDTO;
import com.liming.common.pojo.vo.PageVO;
import com.liming.common.pojo.vo.coupon.mini.MiniCanUseCouponVO;
import com.liming.common.pojo.vo.coupon.mini.MiniCannotUseCouponVO;
import com.liming.common.pojo.vo.coupon.mini.MiniOrderCouponVO;
import com.liming.common.pojo.vo.coupon.openfeign.FeignMiniCanUseCouponVO;
import com.liming.common.pojo.vo.coupon.openfeign.FeignMiniCannotUseCouponVO;
import com.liming.common.pojo.vo.order.OrderVO;
import com.liming.common.pojo.vo.order.mini.*;
import com.liming.common.pojo.vo.order.openfeign.mini.FeignMiniOrderSelectCouponVO;
import com.liming.common.pojo.vo.order.web.RefundOrderVO;
import com.liming.common.util.BeanUtils;
import com.liming.coupon.client.CouponUserClient;
import com.liming.order.client.UserOrderClient;
import com.liming.order.client.UserRefundOrderClient;
import com.liming.shop.client.ShopClient;
import com.liming.user.service.OrderService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author liming
 * @date 2025/4/1
 */
@Slf4j
@Service
@AllArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final CouponUserClient couponUserClient;
    private final UserOrderClient userOrderClient;
    private final UserRefundOrderClient userRefundOrderClient;
    private final AfterSalesClient afterSalesClient;
    private final UserAuthClient userAuthClient;
    private final ShopClient shopClient;

    @Override
    public MiniOrderCouponVO orderCoupon(Integer amount) {
        MiniOrderCouponVO vo = new MiniOrderCouponVO();
        List<FeignMiniCanUseCouponVO> feignCanUseCoupons = couponUserClient.canUseCouponsByAmount(amount);
        List<FeignMiniCannotUseCouponVO> feignMiniCannotUseCoupons = couponUserClient.cannotUseCouponsByAmount(amount);
        List<MiniCanUseCouponVO> canUseCoupons = BeanUtils.toBean(feignCanUseCoupons, MiniCanUseCouponVO.class);
        List<MiniCannotUseCouponVO> cannotUseCoupons = BeanUtils.toBean(feignMiniCannotUseCoupons, MiniCannotUseCouponVO.class);
        vo.setCanUseCouponList(canUseCoupons);
        vo.setCannotUseCouponList(cannotUseCoupons);
        return vo;
    }

    @Override
    public MiniOrderSelectCouponVO selectCoupon(MiniOrderSelectCouponDTO dto) {
        FeignMiniOrderSelectCouponVO feignVo = couponUserClient.miniOrderSelectCoupon(dto);
        MiniOrderSelectCouponVO vo = new MiniOrderSelectCouponVO();
        vo.setAfterCouponOrderAmount(feignVo.getAfterCouponOrderAmount());
        vo.setProductList(BeanUtils.toBean(feignVo.getProductList(), MiniOrderProductVO.class));
        return vo;
    }

    @Override
    public PageVO<MiniOrderVO> page(MiniOrderQueryPage queryPage) {
        return userOrderClient.page(queryPage);
    }

    @Override
    public MiniOrderDetailVO detail(Long id) {
        MiniOrderDetailVO result = new MiniOrderDetailVO();

        CompletableFuture<OrderVO> orderVOFuture = CompletableFuture.supplyAsync(() -> userOrderClient.detailById(id));
        CompletableFuture<List<MiniOrderItemVO>> itemsFuture = CompletableFuture.supplyAsync(() -> userOrderClient.itemsById(id));
        CompletableFuture<Integer> canCommentFuture = CompletableFuture.supplyAsync(() -> afterSalesClient.canComment(id));
        CompletableFuture<String> addressFuture = orderVOFuture.thenCompose(orderVO -> {
            Integer pickup = orderVO.getPickup();
            Long userAddressId = orderVO.getUserAddressId();
            Long pickupPointId = orderVO.getPickupPointId();
            if (ObjectUtil.isNotNull(userAddressId) && ObjectUtil.equal(pickup, OrderPickupEnum.DELIVERY.getCode())) {
                return CompletableFuture.supplyAsync(() -> userAuthClient.addressInfoByIds(List.of(userAddressId)).getOrDefault(userAddressId, ""));
            }
            return CompletableFuture.supplyAsync(() -> shopClient.pickupPointInfoById(pickupPointId));
        });
        CompletableFuture.allOf(orderVOFuture, itemsFuture, canCommentFuture, addressFuture).join();
        OrderVO orderVO = orderVOFuture.join();
        org.springframework.beans.BeanUtils.copyProperties(orderVO, result);
        result.setItems(itemsFuture.join());
        result.setCouponAmount(orderVO.getTotalAmount().subtract(orderVO.getRealAmount()));
        result.setPayType(1);
        String usernamePhoneAddress = addressFuture.join();
        String[] split = usernamePhoneAddress.split("/");
        result.setContactName(split[0]);
        result.setContactPhone(split[1]);
        result.setContactAddress(split[2]);
        result.setCanComment(canCommentFuture.join());
        return result;
    }

    @Override
    public Boolean cancel(Long id) {
        return userOrderClient.cancel(id);
    }

    @Override
    public Boolean complete(Long id) {
        return userOrderClient.complete(id);
    }

    @Override
    public Boolean createOrderPaySuccess(Long id) {
        return userOrderClient.createOrderPaySuccess(id);
    }

    @Override
    public Boolean evaluate(MiniOrderEvaluateDTO miniOrderEvaluateDTO) {
        return afterSalesClient.evaluate(miniOrderEvaluateDTO);
    }

    @Override
    public Boolean refund(Long id, String reason) {
        return userRefundOrderClient.refund(id, reason);
    }

    @Override
    public RefundOrderVO refundDetail(Long id) {
        return userRefundOrderClient.refundDetail(id);
    }
}
